import pyautogui
import pydirectinput
import time, datetime
import ctypes, sys
import aircv as ac
import numpy as np
import tkinter as tk
import os
import pyperclip
import re

MOUSE_POS = [[0] * 2 for _ in range(11)]  # 坐标点组

firstOpenMap = 1 # 第一次打开地图，地图最小化
remaining = 10 # 剩余押镖次数
escortPlace = 1 # 0:东岳；1:杭州；2:开封；3:徐海
escortType = 0 # 0:银两镖；1:碎银镖
role = 0 # 0:队长；1:队员
flyOrFoot = 0 # 0:使用花钱传送；1:不使用花钱传送（不包含第一次去）
gotoFirst = 1 # 0:非第一次去押镖点；1:第一次去押镖点
needShout = 0 # 0:不喊话；1:喊话
temp_XY = (0, 0)
running_log = open("log.txt","w")

choice_UI = {"国服":("血条颜色","传送颜色"),"国际服":("血条颜色","传送颜色")}
choice_addr = {0:-45,1:-20,2:10,3:40} # 0:东岳；1:杭州；2:开封；3:徐海
choice_dongyue = {0:(1486,2479), 1:(591,3168), 2:(584,3174)}
choice_hangzhou = {0:(1173,2455), 1:(2243,2651), 2:(2235,2652)}
choice_kaifeng = {0:(1842,488), 1:(1038,1428), 2:(1030,1424)}
choice_xuhai = {0:(1582,2405), 1:(2338,1720), 2:(2339,1712)}
choice_place = {0:choice_dongyue, 1:choice_hangzhou, 2:choice_kaifeng, 3:choice_xuhai}

# 移动鼠标（X坐标，Y坐标，移动时间）
def moveMouseTo(x, y):
    pydirectinput.moveTo(x, y)


#获取鼠标位置
def getCursorPos(i):
    MOUSE_POS[i][0], MOUSE_POS[i][1] = pydirectinput.position()

# 移动鼠标并点击1次（X坐标，Y坐标，移动时间，左键/右键）
def moveMouseAndClick(x, y):
    moveMouseTo(x, y)
    pydirectinput.click()

# 打开地图
def openMap():
    # 需要判断情况
    if(matchImg('img/mapOpened.png') == False):
        pydirectinput.press('m')

# 关闭地图
def closeMap():
    # 需要判断情况
    if(matchImg('img/mapOpened.png')):
        pydirectinput.press('esc')

# 休眠，单位：秒
def delay(t):
    time.sleep(t)

# 寻找游戏窗口
def findWindow():
    windows = pyautogui.getWindowsWithTitle('天涯明月刀')
    if len(windows) == 0:
        raise Exception("窗口未找到")
    return windows[0]

# 判断是否为管理员权限
def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

# 获取鼠标坐标和颜色
def get_mouse_positon():
    try:
        for i in range(10):
            x, y = pyautogui.position()
            positionStr = '鼠标坐标点(X,Y)为:{},{}'.format(str(x).rjust(4), str(y).rjust(4))
            pix = pyautogui.screenshot().getpixel((x, y))  # 获取鼠标所在屏幕点的RGB颜色
            positionStr += ' RGB:(' + str(pix[0]).rjust(3) + ',' + str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')'
            print(positionStr)
            time.sleep(0.5)  # 停顿时间
    except:
        print('获取鼠标位置失败')
        raise Exception

# 立即传送/付费传送
def transtor():
    im = get_XY_color(820,392)
    if(im[0]==18 and im[1]==45 and im[2] == 68 or im[0]==19 and im[1]==46 and im[2] == 68):
        moveMouseAndClick(811, 395)
    else:
        moveMouseAndClick(924, 393)

# 获取坐标点的颜色
def get_XY_color(x,y):
    return pyautogui.screenshot().getpixel((x, y)) 

# 自动上马
def autoRide():
    delay(0.5)
    pydirectinput.keyDown("ctrl")
    pydirectinput.keyDown("r")
    pydirectinput.keyUp("r")
    pydirectinput.keyUp("ctrl")

# 减少押镖次数
def reduceTimes():
    global remaining
    remaining -= 1
    running_log.write('次数-1\n')

# 将字符串写入剪贴板
def addToClipBoard(text):
    command = 'echo ' + text.strip() + '| clip'
    os.system(command)


# 选择要去的押镖点
def gotoPoint(a):
    return choice_place[a]

# 前往坐标点
def gotoByCoordinate(x, y):
    openMap()
    delay(0.5)
    moveMouseAndClick(590, 20) # 点击坐标输入框
    pydirectinput.typewrite(x)
    delay(0.3)
    # pydirectinput.press('tab')
    moveMouseAndClick(681, 20) # 点击坐标输入框
    pydirectinput.typewrite(y)
    moveMouseAndClick(714, 17)  # 点击放大镜
    closeMap()

# 等待过图
def waitForLoading():
    delay(3)
    color = get_XY_color(908, 1012)
    print(color)
    while(color[0]!= 105 and color[1]!= 254 and color[2]!= 126):
        color = get_XY_color(908, 1012)
        print("not OK")
        delay(1)
    print("That's OK")
    delay(5)

#找图返回坐标
def matchImg(filePath):
    running_log.write('找图：'+ filePath + '\n')
    screenshotIm = pyautogui.screenshot()
    imgsrc = np.array(screenshotIm)  # 打开查找页(全屏)
    imgobj = ac.imread(filePath)  # 打开待识别的图片
    match_result = ac.find_all_template(imgsrc, imgobj, 0.9)  # 0.9是识别达标率
    if(len(match_result) != 0):
        global temp_XY
        temp_XY = match_result[0]['result']
        running_log.write('找到图片中心坐标: ( ' + str(temp_XY[0]) + ', ' + str(temp_XY[1]) + ')\n')
        return True
    else:
       running_log.write('未找到。。。\n')
       return False


# 快速前往押镖点/第一次前往押镖点    
def gotoDestQuick():
    delay(1)
    openMap()   # 打开地图
    delay(0.5)
    moveMouseAndClick(15, 15)    # 打开大世界地图
    delay(0.3)
    moveMouseAndClick(1500, 700) # 点击杭州
    delay(0.3)
    moveMouseAndClick(856, 848)  # 涌金门传送点
    delay(0.4)
    moveMouseTo(1, 1)
    transtor()
    delay(3)
    waitForLoading()  # 过图
    delay(2)
    gotoByCoordinate('1652', '818')
    autoRide()
    delay(10)
    pydirectinput.press('f')
    delay(2)
    
    if(matchImg("img/choiceplace.png") == True):
        moveMouseAndClick(int(temp_XY[0]), int(temp_XY[1]+choice_addr[escortPlace]))

    waitForLoading()  # 过图
    gotoNPC(0)

# 到NPC附近
def gotoNPC(x):
    running_log.write("到NPC坐标点: x=" + str(choice_place[escortPlace][escortType+1][0]) + ",")
    running_log.write("y=" + str(choice_place[escortPlace][escortType+1][1])+" 处  \n")
    gotoByCoordinate(str(choice_place[escortPlace][escortType+1][0]), str(choice_place[escortPlace][escortType+1][1]))
    if(x):
        autoRide()
    delay(3)
    IsArriveNPC(x)


# 是否到达NPC附近
def IsArriveNPC(x):
    openMap()
    while(matchImg('img/ontheway.png')):
        print('’未到达’')
        delay(10)
    delay(1)
    while(matchImg('img/copy.png')):
        moveMouseAndClick(int(temp_XY[0]),int(temp_XY[1])) # 点击复制
        clipboard = re.split(",",re.split("\(|\)",pyperclip.paste())[1])
        running_log.write(str(clipboard) + '\n')
        if(clipboard[0] == str(choice_place[escortPlace][escortType+1][0]) and clipboard[1] == str(choice_place[escortPlace][escortType+1][1])):
            running_log.write('已到达\n')
            closeMap()  # 关闭地图
        else:
            running_log.write('未到达\n')
            gotoNPC(x)

# 卡红
def waitRed():
        currentTime = datetime.datetime.now().strftime('%S')
        print(currentTime)
        # if(currentTime == '03' or currentTime == '53' or currentTime == '26' or currentTime == '14' or currentTime == '29'):
        if(currentTime == '14'):
            delay(0.8)
            return True
        else:
            return False

# 喊话
def shoutAuto():
    # 脚本侧式中，请勿劫镖，感谢
    pyperclip.copy("自动喊话：我是二手月季，我在侧式自动押镖，请勿劫镖，感谢合作!!!")
    pydirectinput.press("enter")
    pydirectinput.keyDown('ctrl')
    pydirectinput.keyDown('v')
    pydirectinput.keyUp('v')
    pydirectinput.keyUp('ctrl')
    pydirectinput.press("enter")

# 是否押镖完成
def IsEscortFinish():
    if(matchImg('img/finish.png')):
        print("完成押镖。。")
        reduceTimes()
        delay(2)
        pydirectinput.press('esc')
        return True
    else:
        print("未完成押镖。。")
        
        return False

# 开始押镖
def startEscort():
    
    pydirectinput.press('f')  # 对话
    delay(0.3)
    if(matchImg("img/start.png") == True):
        moveMouseAndClick(int(temp_XY[0]), int(temp_XY[1])) # 选择开始押镖
    delay(0.3)
    if(matchImg("img/start_2.png") == True):
        moveMouseAndClick(int(temp_XY[0]+20), int(temp_XY[1]+110)) # 选择确认押镖
    delay(0.3)
    if(matchImg("img/start_3.png") == True):
        while(waitRed() == False):
            delay(1)
        moveMouseAndClick(int(temp_XY[0]-55), int(temp_XY[1]+25)) # 选择确认押镖
    
    delay(2)
    
    pydirectinput.keyDown("shift")  #下马
    pydirectinput.keyDown("w")
    pydirectinput.keyUp("w")
    pydirectinput.keyUp("shift")

    pydirectinput.press('j')  # 上车
    delay(3)
    gotoByCoordinate(str(choice_place[escortPlace][0][0]), str(choice_place[escortPlace][0][1]))
    print('押镖终点： '+str(choice_place[escortPlace][0][0]) + ' ' + str(choice_place[escortPlace][0][1]))
    delay(3)
    i = 0
    while(IsEscortFinish() == False):
        if(needShout==1):
            i += 1
        delay(10)
        if(i == 3):
            i = 0
            shoutAuto()
    delay(2)
    

if __name__ == '__main__':
    
    if is_admin():
        gameWindow = findWindow()
        gameWindow.activate()  # 激活窗口,将窗口最前化
        running_log.write("开始执行...\n")
        addToClipBoard('脚本侧式中，请勿劫镖，感谢')
        if(gotoFirst):
            gotoDestQuick()  # 快速到押镖点
        else:
            gotoNPC(1)  #去NPC那里
        while(remaining > 0):
            running_log.write("准备押镖...\n")
            running_log.write('剩余次数:' + str(remaining) + '\n')
            startEscort()    # 开始押镖
            if(flyOrFoot):
                gotoNPC(1)  #去NPC那里
            else:
                gotoDestQuick()
        
        pyautogui.alert(text='押镖结束', title='叮叮叮', button='OK')
        

    else:
        ctypes.windll.shell32.ShellExecuteW(None,"runas",sys.executable,__file__,None,1)

    
